package com.whfc.wxmp.api.sys.controller;

import com.whfc.base.service.SmsService;
import com.whfc.common.enums.AppType;
import com.whfc.common.result.Result;
import com.whfc.common.result.ResultUtil;
import com.whfc.common.util.JSONUtil;
import com.whfc.common.util.SessionAttr;
import com.whfc.wxmp.annotation.CurrentWxUser;
import com.whfc.common.weixin.bean.OAuthUserInfo;
import com.whfc.entity.dto.login.WxMpLogin;
import com.whfc.fuum.dto.WxUserDTO;
import com.whfc.fuum.dto.WxUserToken;
import com.whfc.fuum.entity.SysUser;
import com.whfc.fuum.entity.WxUser;
import com.whfc.fuum.service.SysUserService;
import com.whfc.wxmp.api.sys.service.WxLoginService;
import com.whfc.wxmp.jwt.JwtUtil;
import com.whfc.wxmp.util.RequestConetxtUtil;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description: 微信小程序用户登录
 * @author: xugcheng
 * @version: 1.0
 * @date: 2019/7/22 10:39
 */
@RestController
@RequestMapping("/mp/api")
public class WxLoginController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @DubboReference(interfaceClass = SmsService.class, version = "1.0.0")
    private SmsService smsService;

    @DubboReference(interfaceClass = SysUserService.class, version = "1.0.0")
    private SysUserService sysUserService;

    @Autowired
    private WxLoginService wxLoginService;

    @PostMapping("appmp/login")
    public Result appMpLogin(@RequestBody @Validated WxMpLogin body) {

        logger.info("APP用户登录,{}", body);
        int loginType = body.getLoginType();
        String phone = body.getPhone();
        String username = body.getUsername();
        String password = body.getPassword();
        SysUser sysUser = sysUserService.appMpLogin(loginType,phone,username,password, body.getCid());

        WxUser wxUser = new WxUser();
        wxUser.setId(sysUser.getId());
        wxUser.setName(sysUser.getUsername());
        wxUser.setPhone(sysUser.getPhone());
        wxUser.setOpenId(sysUser.getPhone());
        wxUser.setAppType(body.getLoginType());
        //用户登录
        // 生成JWT
        String jwt = JwtUtil.generateToken(wxUser, sysUser);

        WxUserDTO userDTO = new WxUserDTO();
        BeanUtils.copyProperties(wxUser, userDTO);

        userDTO.setAccessToken(jwt);
        logger.info("APPMPUA|{}|{}|{}|{}|{}",
                wxUser.getId(), RequestConetxtUtil.getAppType(), RequestConetxtUtil.getPage(),
                "用户登录", "{}");
        return ResultUtil.success(userDTO);
    }


    @PostMapping("wxmp/login")
    public Result wxMpLogin(@RequestBody @Validated WxMpLogin body) {

        logger.info("微信小程序用户登录,{}", body);

        String openId = body.getOpenId();
        String code = body.getCode();
        AppType appType = AppType.parseByValue(body.getAppType());

        //查询微信用户
        WxUser wxUser = wxLoginService.wxMpLogin(appType, openId, code);

        //用户登录
        WxUserToken token = new WxUserToken();
        token.setWxUser(wxUser);
        SecurityUtils.getSubject().login(token);

        WxUserDTO userDTO = new WxUserDTO();
        BeanUtils.copyProperties(wxUser, userDTO);
        logger.info("WXMPUA|{}|{}|{}|{}|{}",
                wxUser.getId(), RequestConetxtUtil.getAppType(), RequestConetxtUtil.getPage(),
                "用户登录", "{}");
        return ResultUtil.success(userDTO);
    }

    @PostMapping("wxmp/update/userinfo")
    @Deprecated
    public Result wxMpUpdateUserInfo(@CurrentWxUser WxUser loginUser, @RequestBody @Validated WxMpLogin body) {
        logger.info("WXMPUA|{}|{}|{}|{}|{}",
                loginUser.getId(), RequestConetxtUtil.getAppType(), RequestConetxtUtil.getPage(),
                "更新用户信息", JSONUtil.toString(body));
        //查询微信用户
        WxUser wxUser = wxLoginService.wxMpUpdateUserInfo(loginUser, body.getEncryptedData(), body.getIv());

        //用户更新
        SecurityUtils.getSubject().getSession().setAttribute(SessionAttr.WXMP_USER, wxUser);

        WxUserDTO userDTO = new WxUserDTO();
        BeanUtils.copyProperties(wxUser, userDTO);
        return ResultUtil.success(userDTO);
    }

    @PostMapping("wxmp/update/v1/userinfo")
    public Result wxMpUpdateUserInfo(@CurrentWxUser WxUser loginUser, @RequestBody @Validated OAuthUserInfo body) {
        logger.info("WXMPUA|{}|{}|{}|{}|{}",
                loginUser.getId(), RequestConetxtUtil.getAppType(), RequestConetxtUtil.getPage(),
                "更新用户信息", JSONUtil.toString(body));
        //查询微信用户
        WxUser wxUser = wxLoginService.wxMpUpdateUserInfo(loginUser, body);

        //用户更新
        SecurityUtils.getSubject().getSession().setAttribute(SessionAttr.WXMP_USER, wxUser);

        WxUserDTO userDTO = new WxUserDTO();
        BeanUtils.copyProperties(wxUser, userDTO);
        return ResultUtil.success(userDTO);
    }

    @PostMapping(value = "wxmp/authc", params = "loginType=1")
    public Result authcQuick(@CurrentWxUser WxUser loginUser, @RequestBody WxMpLogin body) {
        logger.info("WXMPUA|{}|{}|{}|{}|{}",
                loginUser.getId(), RequestConetxtUtil.getAppType(), RequestConetxtUtil.getPage(),
                "微信快捷登录", JSONUtil.toString(body));
        //查询微信用户
        WxUser wxUser = wxLoginService.wxMpUpdateUserInfo(loginUser, body.getEncryptedData(), body.getIv());

        //用户更新
        SecurityUtils.getSubject().getSession().setAttribute(SessionAttr.WXMP_USER, wxUser);

        WxUserDTO userDTO = new WxUserDTO();
        BeanUtils.copyProperties(wxUser, userDTO);
        return ResultUtil.success(userDTO);
    }

    @PostMapping(value = "wxmp/authc", params = "loginType=2")
    public Result authcPhone(@CurrentWxUser WxUser loginUser, @RequestBody WxMpLogin body) {
        logger.info("WXMPUA|{}|{}|{}|{}", RequestConetxtUtil.getAppType(), RequestConetxtUtil.getPage(),
                "手机号验证码登录", JSONUtil.toString(body));

        String phone = body.getPhone();
        String code = body.getCode();
        //校验手机验证码
        smsService.checkSmsCode(phone, code);

        if (loginUser == null) {
            SysUser sysUser = sysUserService.appMpLogin(3,phone,phone,phone, body.getCid());

            WxUser wxUser = new WxUser();
            wxUser.setId(sysUser.getId());
            wxUser.setName(sysUser.getUsername());
            wxUser.setPhone(sysUser.getPhone());
            wxUser.setOpenId(sysUser.getPhone());
            wxUser.setAppType(body.getLoginType());
            // 生成JWT
            String jwt = JwtUtil.generateToken(wxUser, sysUser);

            WxUserDTO userDTO = new WxUserDTO();
            BeanUtils.copyProperties(wxUser, userDTO);

            userDTO.setAccessToken(jwt);
            return ResultUtil.success(userDTO);
        }
        //查询微信用户
//        wxUserService.updateUserPhone(loginUser, phone);

        //用户更新
//        loginUser.setPhone(phone);
//        SecurityUtils.getSubject().getSession().setAttribute(SessionAttr.WXMP_USER, loginUser);

        WxUserDTO userDTO = new WxUserDTO();
        BeanUtils.copyProperties(loginUser, userDTO);
        return ResultUtil.success(userDTO);
    }

    @PostMapping(value = "wxmp/authc", params = "loginType=3")
    public Result authcAccount(@CurrentWxUser WxUser loginUser, @RequestBody WxMpLogin body) {
        logger.info("WXMPUA|{}|{}|{}|{}|{}",
                loginUser.getId(), RequestConetxtUtil.getAppType(), RequestConetxtUtil.getPage(),
                "账号密码登录", JSONUtil.toString(body));
        //查询微信用户
        WxUser wxUser = wxLoginService.wxMpUpdateUser(loginUser, body.getUsername(), body.getPassword());

        //用户更新
        SecurityUtils.getSubject().getSession().setAttribute(SessionAttr.WXMP_USER, wxUser);

        WxUserDTO userDTO = new WxUserDTO();
        BeanUtils.copyProperties(wxUser, userDTO);
        return ResultUtil.success(userDTO);
    }

    @GetMapping("serverTime")
    public Result getServerTime(@CurrentWxUser WxUser loginUser) {
        logger.info("获取服务器时间,loginUser:{}", loginUser.getId());
        Map<String, Date> serverTime = new HashMap<>(1);
        serverTime.put("serverTime", new Date());
        return ResultUtil.success(serverTime);
    }

}
